#include "Top.h"
#include "Server.h"
#include "TopMessage.h"

#include <algorithm>

Top::Top(void)
{
	mElementsSem = CreateSemaphore(NULL, 1, 1, NULL);
}


Top::~Top(void)
{
	CloseHandle(mElementsSem);
}


void Top::UpdateBounds(bool _broadcastUpdates)
{
	WaitForSingleObject(mElementsSem, INFINITE);
		if( mElements.size() == 0)
		{
			mLowerPont = 0;
			mHigherPont = 0;
			ReleaseSemaphore(mElementsSem, 1, NULL);
			if( _broadcastUpdates)
				Server::Instance()->BroadcastGameStats();
			return;
		}

		sort(mElements.begin(), mElements.end(), Top::Order);

		mLowerPont = mElements[0].AllTimePoints();
		mHigherPont = mElements[0].AllTimePoints();

		for(vector<Player>::iterator it = mElements.begin(); it != mElements.end(); it++)
		{
			mHigherPont = it->AllTimePoints() > mHigherPont ? it->AllTimePoints() : mHigherPont;
			mLowerPont = it->AllTimePoints() < mLowerPont ? it->AllTimePoints() : mLowerPont;
		}
	ReleaseSemaphore(mElementsSem, 1, NULL);

	Save();

}


bool Top::Order( Player& _p1, Player& _p2 )
{
	return _p1.AllTimePoints() > _p2.AllTimePoints();
}

vector<Player> Top::GetElements()
{
	vector<Player> ret;
	WaitForSingleObject(mElementsSem, INFINITE);
		for(vector<Player>::iterator it = mElements.begin(); it != mElements.end(); it++)
			ret.push_back(*it);
	ReleaseSemaphore(mElementsSem, 1, NULL);

	return ret;
}

void Top::RemoveElement( Player& _newPlayer )
{
	WaitForSingleObject(mElementsSem, INFINITE);
	for(vector<Player>::iterator it = mElements.begin(); it != mElements.end(); it++)
		if( it->Username() == _newPlayer.Username())
		{
			mElements.erase(it);
			break;
		}
	ReleaseSemaphore(mElementsSem, 1, NULL);

	UpdateBounds();
}

bool Top::ElementExists( Player& _player )
{
	WaitForSingleObject(mElementsSem, INFINITE);
	for(vector<Player>::iterator it = mElements.begin(); it != mElements.end(); it++)
		if( it->Username() == _player.Username())
		{
			ReleaseSemaphore(mElementsSem, 1, NULL);
			return true;
		}

	ReleaseSemaphore(mElementsSem, 1, NULL);

	return false;
}

void Top::Reset()
{
	WaitForSingleObject(mElementsSem, INFINITE);
		mElements.clear();
	ReleaseSemaphore(mElementsSem, 1, NULL);
}

